﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace Pavilion
{
    public class AnimationXmlSerializer
    {
        public XDocument SerializeCollection(IEnumerable<Animation> animationCollection)
        {
            XDocument xmlDocument = new XDocument();

            XElement animationCollectionXElement = new XElement("AnimationCollection");
            foreach (Animation animation in animationCollection)
                animationCollectionXElement.Add(Serialize(animation));

            xmlDocument.Add(new XElement("Script", animationCollectionXElement));

            return xmlDocument;
        }

        public IEnumerable<Animation> DeserializeCollection(string animatoinXmlListPath)
        {
            IEnumerable<XElement> animationXElementList = XDocument.Load(animatoinXmlListPath).Element("Script").Element("AnimationCollection").Elements("Animation");
            List<Animation> animationList = new List<Animation>();

            foreach (XElement animationXElement in animationXElementList)
                animationList.Add(Deserialize(animationXElement));

            return animationList;
        }

        public XElement Serialize(Animation animation)
        {
            XElement animationElement = new XElement("Animation");

            animationElement.Add(new XAttribute("Name", animation.Name));
            animationElement.Add(new XAttribute("IsReverse", animation.IsReverse));

            animationElement.Add(SerializeFrameCollection(animation.FrameList));

            return animationElement;
        }

        public Animation Deserialize(XElement animationXElement)
        {
            List<Frame> frameList = DeserializeFrameCollection(animationXElement);

            Animation animation = new Animation(frameList)
            {
                Name = animationXElement.Attribute("Name").Value,
                IsReverse = bool.Parse(animationXElement.Attribute("IsReverse").Value),
            };

            return animation;
        }

        private XElement SerializeFrameCollection(IEnumerable<Frame> frameCollection)
        {
            XElement frameCollectionXElement = new XElement("FrameCollection");

            foreach (Frame frame in frameCollection)
                frameCollectionXElement.Add(SerializeFrame(frame));

            return frameCollectionXElement;
        }

        private List<Frame> DeserializeFrameCollection(XElement animationXElement)
        {
            List<Frame> frameList = new List<Frame>();
            IEnumerable<XElement> frameXElementList = animationXElement.Element("FrameCollection").Elements("Frame");

            foreach (XElement frameXElement in frameXElementList)
                frameList.Add(DeserializeFrame(frameXElement));
            return frameList;
        }

        private XElement SerializeFrame(Frame frame)
        {
            return new XElement("Frame", new XAttribute("Origin", frame.OriginX + "," + frame.OriginY));
        }

        private Frame DeserializeFrame(XElement frameElement)
        {
            float[] originList = ParseMulipleFloatNumbers(frameElement.Attribute("Origin").Value);

            Frame frame = new Frame()
            {
                OriginX = originList[0],
                OriginY = originList[1]
            };
            
            return frame;
        }

        private int[] ParseMulipleIntNumbers(string multipleNumbers)
        {
            List<int> multipleNumbersList = new List<int>();

            foreach (string stringNumber in multipleNumbers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                multipleNumbersList.Add(Int32.Parse(stringNumber.Trim()));

            return multipleNumbersList.ToArray();
        }

        private float[] ParseMulipleFloatNumbers(string multipleNumbers)
        {
            List<float> multipleNumbersList = new List<float>();

            foreach (string stringNumber in multipleNumbers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                multipleNumbersList.Add(float.Parse(stringNumber.Trim()));

            return multipleNumbersList.ToArray();
        }
    }
}
